﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Reflection;
using System.Threading;

namespace DotNet.Common
{
   
    public class DotConvert
    {
        private static readonly object objSync = new object();
        /// <summary>
        /// 将DataTable转换为list
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static IList<T> DataTableToList<T>(DataTable dt)
        { 
            IList<T> result = new List<T>();
            try
            {
                Monitor.Enter(objSync);
                if (dt == null)
                    return null;

                for (int j = 0; j < dt.Rows.Count; j++)
                {
                    T _t = (T)Activator.CreateInstance(typeof(T));
                    PropertyInfo[] propertys = _t.GetType().GetProperties();
                    foreach (PropertyInfo pi in propertys)
                    {
                        for (int i = 0; i < dt.Columns.Count; i++)
                        {
                            // 属性与字段名称一致的进行赋值 
                            if (pi.Name.ToLower().Equals(dt.Columns[i].ColumnName.ToLower()))
                            {
                                if (dt.Rows[j][i] != DBNull.Value)
                                {
                                    if (pi.PropertyType.ToString() == "System.Int32" || pi.PropertyType.ToString() == "System.Nullable`1[System.Int32]")
                                    {
                                        pi.SetValue(_t, Int32.Parse(dt.Rows[j][i].ToString()), null);
                                    }
                                    if (pi.PropertyType.ToString() == "System.DateTime" || pi.PropertyType.ToString() == "System.Nullable`1[System.DateTime]")
                                    {
                                        pi.SetValue(_t, Convert.ToDateTime(dt.Rows[j][i].ToString()), null);
                                    }
                                    if (pi.PropertyType.ToString() == "System.String")
                                    {
                                        pi.SetValue(_t, dt.Rows[j][i].ToString(), null);
                                    }
                                    if (pi.PropertyType.ToString() == "System.Boolean")
                                    {
                                        pi.SetValue(_t, Convert.ToBoolean(dt.Rows[j][i].ToString()), null);
                                    }
                                    if (pi.PropertyType.ToString() == "System.Nullable`1[System.Decimal]")
                                    {
                                        pi.SetValue(_t, Convert.ToDecimal(dt.Rows[j][i].ToString()), null);
                                    }
                                }
                                else
                                    pi.SetValue(_t, null, null);
                                break;
                            }
                        }
                    }
                    result.Add(_t);
                }
            }
            finally
            {
                Monitor.Exit(objSync);
            }
            return result;
        }

        #region 建议使用这种方式转换
        public static IList<T> GetList<T>(DataTable table)
        {
            IList<T> list = new List<T>();
            T t = default(T);
            PropertyInfo[] propertypes = null;
            string tempName = string.Empty;
            try
            {
                Monitor.Enter(objSync);
                foreach (DataRow row in table.Rows)
                {
                    t = Activator.CreateInstance<T>();
                    propertypes = t.GetType().GetProperties();
                    foreach (PropertyInfo pro in propertypes)
                    {
                        tempName = pro.Name;
                        if (table.Columns.Contains(tempName))
                        {
                            object value = row[tempName];
                            if (value == DBNull.Value)
                                value = null;
                            pro.SetValue(t, value, null);
                        }
                    }
                    list.Add(t);
                }
            }
            finally
            {
                Monitor.Exit(objSync);
            }
            return list;
        }
        #endregion


    }
}
